﻿using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using Common.Logging;
using Newtonsoft.Json;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.Entities;
using Senparc.Weixin.MP.Entities.Request;
using User.Api.Models;

namespace User.Api.Controllers
{
    public class WxDockingController : ApiController
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(WxDockingController));

        //与微信公众账号后台的Token设置保持一致，区分大小写。
        public static readonly string Token = ConfigurationManager.AppSettings["WeixinToken"];
        //与微信公众账号后台的EncodingAESKey设置保持一致，区分大小写。
        public static readonly string EncodingAESKey = ConfigurationManager.AppSettings["WeixinEncodingAESKey"];
        //与微信公众账号后台的AppId设置保持一致，区分大小写。
        public static readonly string AppId = ConfigurationManager.AppSettings["WeixinAppId"];

        /// <summary>
        /// 微信后台验证地址（使用Get），微信后台的“接口配置信息”的Url填写如：http://weixin.senparc.com/weixin
        /// </summary>
        [Route("WeiXin")]
        [HttpGet]
        [AllowAnonymous]
        public HttpResponseMessage Validate([FromUri]PostModel postModel, string echostr)
        {
            if (CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
            {
                //返回随机字符串则表示验证通过
                return Request.CreateResponse(HttpStatusCode.OK, echostr, MediaTypeHeaderValue.Parse("text/plain"));
            }
            else
            {
                var responseStr = string.Format("failed:{0},{1}。如果你在浏览器中看到这句话，说明此地址可以被作为微信公众账号后台的Url，请注意保持Token一致。",
                    postModel.Signature, CheckSignature.GetSignature(postModel.Timestamp, postModel.Nonce, Token));
                return Request.CreateResponse(HttpStatusCode.OK, responseStr, MediaTypeHeaderValue.Parse("text/plain"));
            }
        }

        /// <summary>
        /// 用户发送消息后，微信平台自动Post一个请求到这里，并等待响应XML。
        /// </summary>
        [Route("WeiXin")]
        [HttpPost]
        [AllowAnonymous]
        public HttpResponseMessage Main([FromUri]PostModel postModel)
        {
            if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
            {
                return Request.CreateResponse(HttpStatusCode.OK, "参数错误！", MediaTypeHeaderValue.Parse("text/plain"));
            }

            postModel.Token = Token;//根据自己后台的设置保持一致
            postModel.EncodingAESKey = EncodingAESKey;//根据自己后台的设置保持一致
            postModel.AppId = AppId;//根据自己后台的设置保持一致

            //可以设置每个人上下文消息储存的最大数量，防止内存占用过多，如果该参数小于等于0，则不限制
            var maxRecordCount = 1;

            //设置默认微信消息上下文的过期时间
            WxCustomMessageHandler.GlobalWeixinContext.ExpireMinutes = 3;

            //自定义MessageHandler，对微信请求的详细判断操作都在这里面。
            var messageHandler =
                new WxCustomMessageHandler(Request.Content.ReadAsStreamAsync().Result, postModel, maxRecordCount);

            try
            {
                Logger.DebugFormat("收到微信消息 ： {0}", messageHandler.RequestDocument.ToString());
                if (messageHandler.UsingEcryptMessage)
                {
                    Logger.DebugFormat("收到微信加密消息 ： {0}", messageHandler.EcryptRequestDocument.ToString());
                }

                /* 如果需要添加消息去重功能，只需打开OmitRepeatedMessage功能，SDK会自动处理。
                 * 收到重复消息通常是因为微信服务器没有及时收到响应，会持续发送2-5条不等的相同内容的RequestMessage*/
                messageHandler.OmitRepeatedMessage = true;

                //执行微信处理过程
                messageHandler.Execute();

                if (messageHandler.ResponseDocument != null)
                {
                    Logger.DebugFormat("回复被动消息 : {0}", messageHandler.ResponseDocument.ToString());
                }
                if (messageHandler.UsingEcryptMessage)
                {
                    Logger.DebugFormat("回复加密被动消息 : {0}", messageHandler.FinalResponseDocument.ToString());
                }

                if (messageHandler.ResponseMessage.MsgType == ResponseMsgType.Text
                    && string.IsNullOrEmpty(((ResponseMessageText)messageHandler.ResponseMessage).Content))
                {
                    return Request.CreateResponse(HttpStatusCode.OK,
                    "success"
                    , MediaTypeHeaderValue.Parse("text/plain"));
                }

                return Request.CreateResponse(HttpStatusCode.OK,
                    messageHandler.FinalResponseDocument.ToString()
                    , MediaTypeHeaderValue.Parse("text/plain"));
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("处理微信消息时发生错误，信息:{0}", JsonConvert.SerializeObject(ex));
                return Request.CreateResponse(HttpStatusCode.OK, "", MediaTypeHeaderValue.Parse("text/plain"));
            }
        }
    }
}
